package infolayer2.graph;

import java.util.Map;

import com.google.common.collect.Maps;

public class Node {
  private Map<String,EdgeSet> properties = Maps.newTreeMap();
  // The id used when creating new edges
  private String id;
  
  public Node(String id) {
    this.id = id;
    addValue("/type/object/id", id);
  }
  
  public void setValue(String propertyName, Object value) {
    properties.put(propertyName, new EdgeSet());
    addValue(propertyName, value);
  }

  public void setReference(String propertyName, String to) {
    properties.put(propertyName, new EdgeSet());
    addReference(propertyName, to);
  }

  public void addValue(String propertyName, Object value) {
    EdgeSet values = getOrCreateValues(propertyName);
    values.add(new Edge(id, propertyName, null, value));
  }

  public void addReference(String propertyName, String to) {
    EdgeSet values = getOrCreateValues(propertyName);
    values.add(new Edge(id, propertyName, to, null));
  }

  private EdgeSet getOrCreateValues(String propertyName) {
    if (!propertyName.startsWith("/")) {
      throw new IllegalArgumentException("property name must include the full namespace and start with '/'");
    }
    propertyName = propertyName.intern();
    EdgeSet values = properties.get(propertyName);
    if (values == null) {
      values = new EdgeSet();
      properties.put(propertyName, values);
    }
    return values;
  }

  public EdgeSet get(String propertyName) {
    EdgeSet values = properties.get(propertyName);
    return (values == null) ? EdgeSet.EMPTY : values;
  }
  
  public void addType(String type) {
    addReference("/type/object/type", type);
  }

  public String toString() {
    StringBuilder sb = new StringBuilder("{\n");
    for (Map.Entry<String, EdgeSet> entry: properties.entrySet()) {
      sb.append("  '");
      sb.append(entry.getKey());
      sb.append("': ");
      sb.append(entry.getValue());
      sb.append(",\n");
    }
    sb.append("}");
    return sb.toString();
  }
  
  public Iterable<String> propertyNames() {
    return properties.keySet();
  }


  public String getId() {
    return id;
  }
}
